#ifndef MYHEAD_MYOWNLIB
#define MYHEAD_MYOWNLIB

#include<iostream>
#include"fstream"
#include"errno.h"
#include"vector"
#include"string"

#include"mlibh.h"

//#define MY_USE_OPENCV
//#define MY_USE_QT
//#define MY_USE_POINT_IO
//#define MY_USE_VTK
//#define MY_USE_ITK
//#define MY_USE_PCL
//#define MY_USE_MATLAB


#include<iostream>
using namespace std;
typedef unsigned char uchar;

#ifdef MY_USE_OPENCV

#include "opencv2/opencv.hpp"
//using namespace cv;
#endif


#ifdef MY_USE_MATLAB

#include<matrix.h>

#endif


#ifdef MY_USE_QT

#include<QString>
#include <QImage>
#include"QGraphicsScene"
#include"QGraphicsView"
#include"QGraphicsPixmapItem"
#include"QDir"
#include"QFile"
#include<QString>
#include<QFileDialog>

#endif




#ifdef MY_USE_VTK

#include"vtkPoints.h"
#include"vtkPolyVertex.h"
#include"vtkUnstructuredGrid.h"
#include"vtkRenderWindow.h"
#include"vtkDataSetMapper.h"
#include"vtkActor.h"
#include"vtkProperty.h"
#include"vtkRenderer.h"
#include"vtkInteractorStyleSwitch.h"
#include"vtkSmartPointer.h"
#include"vtkSurfaceReconstructionFilter.h"
#include"vtkReverseSense.h"
#include"vtkContourFilter.h"
#include"vtkUnstructuredGridAlgorithm.h"
#include"vtkTransform.h"
#include"vtkTransformPolyDataFilter.h"
#include"vtkPLYReader.h"
#include"vtkCellArray.h"
#include"vtkPlane.h"
#include"vtkPolyDataWriter.h"
#include"vtkXMLPolyDataWriter.h"
#include"vtkGenericDataObjectReader.h"
#include"vtkPointSet.h"
#include"vtkCutter.h"
#include"vtkPointData.h"
#include"vtkDelaunay2D.h"
#include"vtkDelaunay3D.h"
#include"vtkCleanPolyData.h"
#include"vtkGeometryFilter.h"
#include"vtkKdTree.h"
#include"vtkKdTreePointLocator.h"
#include"vtkPointSource.h"
#include"vtkMath.h"
#include"vtkIdList.h"

#include"vtkSelection.h"
#include"vtkSelectionNode.h"
#include"vtkIdTypeArray.h"
#include"vtkExtractSelection.h"
#include"vtkInformation.h"
//#include"itkimagetov"
extern void insertpointspieaces(vector<vtkSmartPointer<vtkPointSet> > &psl);
extern void  processpointspieaces(vector<vtkSmartPointer<vtkPointSet> > &psl,int maxdis=5);
extern vtkSmartPointer<vtkPolyData> fixpolydatabybound(vtkSmartPointer<vtkPolyData> src,vtkSmartPointer<vtkPolyData> bound,bool inverse=false);
extern  vtkSmartPointer<vtkPolyData> points2polywithver(vtkSmartPointer<vtkPoints>);
extern vtkSmartPointer<vtkPolyData> exactouterconn(vtkSmartPointer<vtkPolyData> src);
extern vtkSmartPointer<vtkPolyData> exactsurface2d(vtkSmartPointer<vtkPolyData> src,double stemp=0.5);
extern vtkSmartPointer<vtkPolyData> removescalar(vtkSmartPointer<vtkPolyData> poly);
extern vtkSmartPointer<vtkPolyData> topolydata( vtkSmartPointer< vtkDataObject> src);

extern  vtkSmartPointer<vtkUnstructuredGrid> getunstructgrid(const char * dirname);

extern vtkSmartPointer<vtkPolyData> getsurface(vtkSmartPointer<vtkPoints> points,int neiborsize=-1,double space=-1);

 extern vtkSmartPointer< vtkPoints> projectPoints( vtkSmartPointer< vtkPoints> pt0,double direct[]);

 extern vtkSmartPointer<vtkPolyData> readvtk(const char * filename);
  void savevtk( vtkSmartPointer<vtkPoints> points,const char * filename="out.vtk");
 void savevtk( vtkSmartPointer<vtkPolyData> poly,const char * filename="out.vtk");
#endif



#ifdef MY_USE_QT
extern std::ostream & operator << (std::ostream & out,QString qstring);
extern QString getchoosefile(QWidget * parent,string files="text(*.txt);;all(*)",QString dir=QString());
extern QString getchoosefolder(QWidget * parent,QString dir=".");
extern QStringList getfilesfromfolder(string folder,string ext="*");

extern int qgs_showimg(QGraphicsScene * qgs, QImage qi,int newimg=1,QGraphicsPixmapItem * oldqgpi=0);
#ifdef MY_USE_OPENCV
extern int qgs_showimg(QGraphicsScene * qgs, cv::Mat m, int chanel=3,int newimg=1,QGraphicsPixmapItem *oldqgpi=0);
#endif
extern void qgv_fitsize(QGraphicsView * qgv,QGraphicsPixmapItem * qgi);

#endif



#ifdef MY_USE_MATLAB
extern int Mat2mxArray(const Mat & mat,mxArray * & ma);
extern int mxArray2Mat(const mxArray * ma,Mat &m);

#endif


#ifdef MY_USE_OPENCV
#ifdef MY_USE_QT
extern int mat2qimage(const cv::Mat& mat,QImage & qim,int chanel=3);//chanel bgr 3 is gray
extern int qimage2mat(const QImage& qi,cv::Mat & matr);

#endif
#endif


#ifdef MY_USE_POINT_IO

using namespace std;

typedef struct mypoint{
  int x,y,z;
}point3d;

typedef vector<point3d> pointset;

typedef vector<pointset> pointsetlist;

class pointio
{

public:
    int xsep=1,ysep=1,zsep=1;
    int processnose=0;
    int expend=1;
    pointio();
    pointset getpointsetformfile(string,int zindex=0);
    void outputpoints(pointset);
    pointsetlist getpointsinfolder(string dirname,int autoz=0);
    int pointdistance(point3d p1,point3d p2);

#ifdef MY_USE_OPENCV
    void points2img(string dirnm,int image2d=0);
#endif

#ifdef MY_USE_VTK
    vtkSmartPointer<vtkPoints> pointlist2poinset(pointsetlist pointlist);
    vector< vtkSmartPointer<vtkPointSet> > pointlist2poinsetvector(pointsetlist pointlist);
     vtkSmartPointer<vtkPoints> mypointset2pointset(pointset pointlist);
     void savevtkpointsets(vector<vtkSmartPointer< vtkPointSet> > pointsets);
#endif
};


#endif

#ifdef MY_USE_VTK

#include"vtkPoints.h"
#include"vtkPolyVertex.h"
#include"vtkUnstructuredGrid.h"
#include"vtkRenderWindow.h"
#include"vtkDataSetMapper.h"
#include"vtkActor.h"
#include"vtkProperty.h"
#include"vtkRenderer.h"
#include"vtkInteractorStyleSwitch.h"
#include"vtkSmartPointer.h"
#include"vtkSurfaceReconstructionFilter.h"
#include"vtkReverseSense.h"
#include"vtkContourFilter.h"
#include"vtkUnstructuredGridAlgorithm.h"
#include"vtkTransform.h"
#include"vtkTransformPolyDataFilter.h"
#include"vtkPLYReader.h"
#include"vtkPolyDataConnectivityFilter.h"
#include"vtkAppendPolyData.h"


#ifdef MY_USE_PCL

#include <pcl/point_types.h>
#include <pcl/features/normal_3d.h>
#include<pcl/io/vtk_lib_io.h>

extern void getnomals(vtkSmartPointer<vtkPolyData> polydata,int redirect=1);


#endif


#endif


#ifdef MY_USE_ITK
#include"itkImage.h"
#include"itkImageFileReader.h"
#include"itkGDCMImageIO.h"
#include"itkMetaDataObject.h"
#include"itkImageSeriesReader.h"
#include"itkGDCMSeriesFileNames.h"



extern itk::Image<signed short,2>::Pointer readdicom(string filename);
extern void getdicomdata(itk::Image<signed short,2>::Pointer,ostream & out=cout);
extern void listtagsfromimage(itk::Image<signed short,2>::Pointer image,bool onlyimportant=false,ostream & out=cout);

extern string searchtagfromimage(itk::Image<signed short,2>::Pointer image,string key="",string label="");

extern void sepratedicom(QString sourcedir,QString destdir,string filter="*");

#ifdef MY_USE_VTK
#include"itkImageToVTKImageFilter.h"
extern vtkSmartPointer<vtkImageData> readdicomfromfolder(string folder);

#endif

#endif

template <class T>
void printarray(T * array,int count){
    int i;
    for(i=0;i<count;i++) cout<<array[i]<<" ";

    cout<<endl;

}

template <class T>
bool boundisin(T *a,T *b,int d=3){
    // (xmin,xmax, ymin,ymax, zmin,zmax).

//    cout<<"boundisin:"<<endl;
//    printarray(a,d*2);
//    printarray(b,d*2);

    if(a[0]>b[0] || a[1]<b[1] || a[2]>b[2] || a[3]<b[3]) return false;
    if(d>2){
        if(a[4]>b[4]||a[5]<b[5]) return false;
    }
    return true;

}
#endif
